<?php
/**
 * 获取给定时间段里的年月日时分数组
 *
 * @author huyan
 */
class DateTimeRange {
	
	public $startTime;
	public $endTime;
	
	public function __construct($startTime = 0, $endTime = 0){
		$this->startTime = is_int($startTime) ? $startTime : strtotime($startTime);
		$this->endTime = is_int($endTime) ? $endTime : strtotime($endTime);
	}
	
	//获取所有年份
	public function getYears(){
		$startYear = intval(date('Y', $this->startTime));
		$endYear = intval(date('Y', $this->endTime));
		$years = array();
		if($startYear < $endYear){
			for($i = $startYear;$i<=$endYear;$i++){
				$years[] = $i;
			}
		}else{
			$years[] = $startYear;
		}
		return $this->formatDate($years);
	}
	
	//获取所有月份
	public function getMonths(){
		$startYear = intval(date('Y', $this->startTime));
		$startMonth = intval(date('m', $this->startTime));
		$endYear = intval(date('Y', $this->endTime));
		$endMonth = intval(date('m', $this->endTime));
		$months = array();
		if($startYear < $endYear){
			//开始年份处理
			for($m=$startMonth;$m<=12;$m++){
				$months[] = $startYear.'-'.$m;
			}
			//中间年份
			for($y=$startYear+1;$y<$endYear;$y++){
				for($m=1;$m<13;$m++){
					$months[] = $y.'-'.$m;
				}
			}
			//结束年份处理
			for($m=1;$m<=$endMonth;$m++){
				$months[] = $endYear.'-'.$m;
			}
		}else{//同一年
			for($m=$startMonth;$m<=$endMonth;$m++){
				$months[] = $startYear.'-'.$m;
			}
		}
		return $this->formatDate($months);
	}
	
	//获取所有周
	public function getWeeks(){
		$startYear = intval(date('Y', $this->startTime));
		$endYear = intval(date('Y', $this->endTime));
		$weeks = array();
		if($startYear < $endYear){
			//开始年份处理
			$startWeek = $this->getWeek($this->startTime);
			for($w=$startWeek;$w<=52;$w++){
				$weeks[] = $startYear.'-'.$w;
			}
			//中间年份
			for($y=$startYear+1;$y<$endYear;$y++){
				$startWeek = $this->getWeek(strtotime($y.'-01-01'));
				$endWeek = $this->getWeek(strtotime($y.'-12-31'));
				for($w=$startWeek;$w<=$endWeek;$w++){
					$weeks[] = $y.'-'.$w;
				}
			}
			//结束年份处理
			$endWeek = $this->getWeek($this->endTime);
			for($w=1;$w<=$endWeek;$w++){
				$weeks[] = $endYear.'-'.$w;
			}
		}else{//同一年
			$startWeek = $this->getWeek($this->startTime);
			$endWeek = $this->getWeek($this->endTime);
			for($w=$startWeek;$w<=$endWeek;$w++){
				$weeks[] = $startYear.'-'.$w;
			}
		}
		return $this->formatDate($weeks);
	}
	
	//获取所有日期
	public function getDays(){
		$lengthTime = $this->endTime - $this->startTime;
		if($lengthTime < 0){//非法参数
			return array();
		}
		$startDate = date('Y-m-d', $this->startTime);
		$startDayTime = strtotime($startDate);
		$step = 24*3600;
		if($lengthTime < $step){
			return array($startDate);
		}
		$days = array();
		while(($this->endTime - $startDayTime) >= 0){
			$days[] = date('Y-m-d', $startDayTime);
			$startDayTime += $step;
		}
		return $this->formatDate($days);
	}
	
	//获取所有日期
	public function getHours(){
		$days = $this->getDays();
		$daysLength = count($days);
		$hours = array();
		if($daysLength == 0){
			return $hours;
		}
		$startHour = intval(date('H', $this->startTime));
		$endHour = intval(date('H', $this->endTime));
		if($daysLength == 1){//同一天
			for($h=$startHour;$h<=$endHour;$h++){
				$hours[] = $days[0].' '.$h;
			}
			return $hours;
		}
		for($h=$startHour;$h<24;$h++){
			$hours[] = $days[0].' '.$h;
		}
		for($d=1;$d<$daysLength-1;$d++){
			for($h=0;$h<24;$h++){
				$hours[] = $days[$d].' '.$h;
			}
		}
		for($h=0;$h<=$endHour;$h++){
			$hours[] = $days[$daysLength-1].' '.$h;
		}
		return $this->formatDate($hours);
	}
	
	//获取所有分钟
	public function getMinutes(){
		$hours = $this->getHours();
		$hoursLength = count($hours);
		$minutes = array();
		if($hoursLength == 0){
			return $minutes;
		}
		$startMinute = intval(date('i', $this->startTime));
		$endMinute = intval(date('i', $this->endTime));
		if($hoursLength == 1){//同一小时
			for($m=$startMinute;$m<=$endMinute;$m++){
				$minutes[] = $hours[0].':'.$m;
			}
			return $minutes;
		}
		for($m=$startMinute;$m<60;$m++){
			$minutes[] = $hours[0].':'.$m;
		}
		for($h=1;$h<$hoursLength-1;$h++){
			for($m=0;$m<60;$m++){
				$minutes[] = $hours[$h].':'.$m;
			}
		}
		for($m=0;$m<=$endMinute;$m++){
			$minutes[] = $hours[$hoursLength-1].':'.$m;
		}
		return $this->formatDate($minutes);
	}
	
	//获取指定时间的周次
	public function getWeek($time){
		$theMonth = intval(date('m', $time));
		$theDay = intval(date('d', $time));
		$theWeek = intval(date('W', $time));
		if($theWeek == '1' && $theWeek < '7'){
			$theWeek = ($theWeek == '53') ? 0 : $theWeek;
		}
		if($theWeek == '12' && $theWeek > '24'){
			$theWeek = ($theWeek == '1') ? 53 : $theWeek;
		}
		return intval($theWeek);
	}
	
	//格式化日期格式
	public function formatDate($dates){
		$preg = '/(?<=[: -])\d((?=[: -])|$)/';
		if(!is_array($dates)){
			return preg_replace($preg, '0\0', $dates);
		}
		return array_map(function($date)use($preg){
			return preg_replace($preg, '0\0', $date);
		}, $dates);
	}
}
